﻿using System;

namespace Lesson5_值类型与引用类型
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 变量类型
            //无符号整形
            byte b = 1;
            short s = 1;
            int i = 1;
            long l = 1;

            //有符号整形
            sbyte sb = 1;
            ushort us = 1;
            uint ui = 1;
            ulong ul = 1;

            //浮点型
            float f = 1.1f;
            double d = 1.1;
            decimal de = 1.1m;

            //特殊类型
            char c = 'A';
            string str = "String";
            bool bo = true;

            //复杂数据类型
            //枚举enum
            //数组(一维 二维 交错)

            //以上变量类型分为 值类型 与 引用类型
            //引用类型：string 数组 类
            //值类型：其他 结构体
            #endregion

            #region 值类型与引用类型的区别
            // 1.使用上的区别
            //申明一个值类型
            int m = 1;
            //申明一个引用类型
            int[] arr1 = { 1, 2, 3 };

            //申明一个整形变量n 将m的值赋给n
            int n = m;
            //申明一个数组arr2 将arr1的值赋给arr2
            int[] arr2 = arr1;

            Console.WriteLine("a = {0} b = {1}", m, n);
            Console.WriteLine("arr1[0] = {0} arr2[1] = {1}", arr1[0], arr2[0]);

            n = 5;
            arr2[0] = 5;

            Console.WriteLine("a = {0} b = {1}", m, n);
            Console.WriteLine("arr1[0] = {0} arr2[1] = {1}", arr1[0], arr2[0]);

            //值类型 在进行赋值时 仅将右侧变量的值赋给左侧 右侧变量值不变 若再次更改左侧变量的值 右侧变量值不变
            //引用类型 在进行赋值时 是将等号两边变量的值都指向右侧变量的值 若再次更改左侧变量的值 右侧变量值也随之改变

            // 2.造成上述区别的原因
            //值类型 与 引用类型存储的内存区域不同 存储的方式不同
            //值类型 存储在栈中 栈由系统分配 当变量超过作用域时 自动释放 空间较小 运算速度快
            //引用类型 本身存储在栈中 它所引用的对象 即它的值存储在堆中 堆需要程序员自行申请与分配 空间较大 运算速度慢

            //引用类型存储在栈中的是地址，值存储在堆中
            //在赋值时，arr1赋给arr2的是栈中的地址
            //因此在改变arr2值时，由于改变的仅仅只是堆中的值，地址不变，因此arr1的值也会发生变化

            //但是若进行如下操作
            arr2 = new int[] { 99, 2, 3 };
            Console.WriteLine("arr1[0] = {0} arr2[1] = {1}", arr1[0], arr2[0]);
            //会发现这次arr1的值并未发生变化，这是因为用new重新申请在堆中分配了空间，地址也发生了变化，arr1和arr2地址不再相同，也就不再指向同一个值
            #endregion

        }
    }
}